/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package view;

import core.DirectoryItem;
import core.FileItem;
import core.FileRoot;
import Tree.DirTree;
import core.IView;
import java.awt.BorderLayout;
import java.awt.Frame;
import drapdrop.MyTransferHandler;
import view.IDirChangedListener;

import java.io.File;
import java.util.Stack;
import java.util.Vector;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.ToolTipManager;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;

import Key.KeyManager;
import Mouse.MouseManager;
import core.DirChangeListener;
import drapdrop.MyTransferHandler;
import javax.swing.DropMode;
import javax.swing.TransferHandler;

/**
 *
 * @author Alex
 */
public class TableView extends JTable implements IView{
    
     /**Thư mục hiện tại của view*/
    protected File _dir;
    /**Danh sách tên cột của view*/
    protected Vector _columnNames;
    /**Danh sách dữ liệu hiện thị của view*/
    protected Vector _data;
    /**Model của view*/
    protected ViewModel _model;
    /**Đánh dấu View đang focus*/
    protected Boolean _isFocus = false;
    /**Danh sách lưu các đối tượng File đã duyệt qua*/
    Stack<File> _stackBackFile;
    /**Danh sách lưu các đối tượng File đã duyệt qua*/
    Stack<File> _stackForwardFile;
    /**Interface listener thông báo sự kiện có sự cập nhật thư mục của view*/
//    protected  IDirChangedListener _changedListener;
    private DirTree _tree;
    private File _oldZipPath = null;
    private File _oldFileZip = null;
    protected  IDirChangedListener _changedListener;
    /**
     * Contructor
     * @param  dir đối tượng File
     * @param  isFocus đối tượng Boolean , nếu true thì view đang focus
     */
    @SuppressWarnings("unchecked")
    public TableView(File dir, Boolean isFocus)
    {
        _dir = dir;
        _isFocus = isFocus;
        _stackBackFile = new Stack<File>();
        _stackForwardFile = new Stack<File>();
        
        initTableData();
        initTable();
    }

    /**
     * Khởi tạo các thuộc tính của bảng
     */
    void initTable()
    {
        this.setShowGrid(false);

        //extension column
        TableColumn co = this.getColumnModel().getColumn(1);
        co.setMinWidth(10);
        co.setMaxWidth(50);
        co.setWidth(20);

        //size column
        co = this.getColumnModel().getColumn(2);
        co.setMinWidth(50);
        co.setMaxWidth(100);
        co.setWidth(60);

        this.setFocusable(true);

        this.addMouseListener(new MouseManager());
        this.addKeyListener(new KeyManager());

        this.setSelectionMode(this.selectionModel.MULTIPLE_INTERVAL_SELECTION);
        //this.setPreferredScrollableViewportSize(this.getPreferredSize());
        //this.setSurrendersFocusOnKeystroke(true);
//        this.setDragEnabled(true);
//        this.setTransferHandler(new MyTransferHandler());
//        this.setDropMode(DropMode.ON_OR_INSERT);
        this.setFillsViewportHeight(true);

        this.getTableHeader().setReorderingAllowed(false);

        BorderLayout layout = new BorderLayout();

        ToolTipManager.sharedInstance().unregisterComponent(this);
        ToolTipManager.sharedInstance().unregisterComponent(this.getTableHeader());
        this.setLayout(layout);

    }

    /**
     * Khởi tạo dữ liệu của bảng
     */
    @SuppressWarnings({"unchecked", "unchecked"})
    void initTableData()
    {
        _columnNames = new Vector(4);
        _columnNames.addElement("Name");
        _columnNames.addElement("Ext");
        _columnNames.addElement("Size");
        _columnNames.addElement("Date");

        _data = new Vector();
        _model = new ViewModel(_data, _columnNames);
        this.setModel((TableModel) _model);
        
        initTableData(_dir.listFiles());       
    }

    /**Khởi tạo dữ liệu của bảng với danh sách các items
     * @param items  danh sách đối tượng kiểu File
     */
    @SuppressWarnings("unchecked")
    private void initTableData(File[] items)
    {
        _data.removeAllElements();

        if (items == null)
        {
            return;
        }

        //add dong dau tien
         if (!DirectoryItem.isPartiton(items[0]))
         {
            Vector firstrow = new Vector(4);
            File dir = DirectoryItem.getParentFolder(_dir);
            firstrow.addElement(new RowParentFolder(dir));

            firstrow.addElement("");//extendsion
            firstrow.addElement("<DIR>");//size

            if (dir instanceof  FileRoot)//date
                firstrow.addElement("");
            else
                firstrow.addElement(FileItem.getDate(_dir));
            _data.addElement(firstrow);
         }

        for (int i = 0; i < items.length; ++i)
        {
            Vector row = new Vector(4);
            row.addElement(items[i]);
            row.addElement(FileItem.getExtension(items[i]));
            row.addElement(FileItem.getSize(items[i]));
            row.addElement(FileItem.getDate(items[i]));

            _data.addElement(row);
        }
    }

    /**
     * Cập nhật nội dung bảng với thư mục xác định
     * @param  dir đối tượng File
     */
    public void refresh(File dir)
    {
        if (dir == null)
        {
            JOptionPane.showMessageDialog(new Frame(),"Can't note load drive.");
            return;
        }
        // ngdlong - Doesn't handle tree at this tiem
//        if (_tree != null)
//        {
//            _tree.expandAtNode(dir);
//        }
        if (_dir.getName().equals(dir.getName()) == false)
        {            
            _stackBackFile.push(_dir);
        }
        _dir = dir;
        refresh();
    }

    /**
     * cập nhật nội dung bảng
     */
    public void refresh()
    {
        // ngdlong - Will add listerner later
//        if (_changedListener != null)
//            _changedListener.dirChanged(_dir);
        
        File[] items = _dir.listFiles();
        initTableData(items);
        _model.setData(_data);
    }

    /**
     * Add xử lý sự kiện khi thư mục hiện hành thay đổi
     * @param  changedListener  đối tượng cài đặt interface IDirChangedListener
     */
//    public void addDirChangeListener(IDirChangedListener changedListener)
//    {
//        _changedListener = changedListener;
//    } ngdlong - add later

    /**
     * Đi tới thư mục sau đó
     */
    public void goBack()
    {
        _stackForwardFile.push(_dir);
        _dir = _stackBackFile.pop();
        refresh();
    }

    /**
     * Đi tới thư mục cha
     */
    public void goForward()
    {
        _dir = _stackForwardFile.pop();
        refresh();
    }

    /**Lấy đường dẫn của thư mục hiện tại
     * @return đối tượng String
     */
    public String getPathCurrentDir()
    {
        //TODO:them vao thumbnails
        if (_dir instanceof FileRoot)
            return ((FileRoot)_dir).getName();
        return  _dir.getAbsolutePath();

    }

    /**
     * Lấy đối tượng File đang chọn
     * @return  đối tượng kiểu File
     */
    public File getCurrentSelectedFile()
    {        
        int irow = this.getSelectedRow();
        Object o = this.getModel().getValueAt(irow, 0);
        File kq = null;
        if(o instanceof File)
            kq = (File) o;
        return kq;
    }

    /**Lấy danh sách đối tượng File đang chọn
     *@return mảng các đối tượng kiểu File
     */
    public File[] getCurrentSelectedFiles()
    {
        int[] irows = this.getSelectedRows();
        File[] kq = new File[irows.length];

        for (int i = 0; i < irows.length; ++i)
        {
            Object o = this.getModel().getValueAt(irows[i], 0);
            if(o instanceof File)
                kq[i] = (File) o; 
        }
        return kq;
    }

    /**
     * Đi tới danh sách các ổ đĩa trong hệ thống
     */
    public void gotoRoots()
    {
        _dir = new FileRoot(".");
        refresh();
        //initTableData(File.listRoots());
        //_model.setData(_data);
    }

    /**
     * Add xử lý sự kiện khi thư mục hiện hành của view thay đổi nó sẽ thông báo cho DirTree
     * @param tree đối tượng kiểu DirTree
     */
    public void addTree(DirTree tree)
    {
        _tree = tree;
    }

    /**
     * Remvo DirTree gán liền với view đã add
     */
    public void removeTree()
    {
        _tree =  null;
    }

    /**
     * Đi tới thư mục cha
     */
    public void goUp()
    {
//        _dir  = DirectoryItem.getParentFolder(_dir);
        refresh();
    }

    /**
     * Lấy đối tượng File của thư mục hiện tại
     * @return đối tượng kiểu File
     */    
    public File getCurrentDir()
    {
        return _dir;
    }

    /**Kiểm tra view có focus không
     * @return trả về đối tượng kiểu Boolean
     */
    public boolean isFocus()
    {
        return _isFocus;
    }

    /**Set focus cho view
     * @param isFocus  đối tượng kiểu Boolean
     */
    public void setFocus(boolean isFocus)
    {
        _isFocus = isFocus;
    }

    /**
     * Add xử lý sự kiện khi drag drog file và thư mục
     * @param  handler  đối tượng kiểu MyTransferHandler
     */
//    public void addTransferHandler(MyTransferHandler handler)
//    {
//        this.setDragEnabled(true);
//        this.setTransferHandler(handler);
//        this.setDropMode(DropMode.ON_OR_INSERT);
//    }

    /**
     * Lấy đối tượng File zip cũ đã lưu
     * @return đối tượng kiểu File
     */
    public File getOldFileZip()
    {
        return _oldFileZip;
    }

    /**
     * Thực thi hành động click lên 1 dòng
     * @param o đối tượng Object là đối tượng đại diện cho dòng thực hiện click
     */
    public void doClick(Object o)
    {
        //TODO:them vao thumbnails
          if (o instanceof RowParentFolder)
            {
              if (_oldZipPath != null)
              {
                  this.refresh(_oldZipPath);
                  //FileItem.deleteFile(_oldZipPath);
                  return;
              }
             
                RowParentFolder temp = (RowParentFolder)o;
                this.refresh(temp.getDir());
            }
            else if (o instanceof File)
            {
                _oldZipPath = null;
                _oldFileZip = null;
                File f = (File) o;
                if (f.isDirectory())
                {
                    this.refresh(f);                    
                }
                else
                {
                    if(FileItem.isZipFile(f) == true)                    
                    {                        
//                        try {
//                            _oldFileZip = f;
//                            f = ZipFiles.ExploreZipFile(f.toString());                            
//                            _oldZipPath = _dir;
//                            this.refresh(f);
//                        } catch (Exception ex) {}
                    }
                    else{
                        FileItem.execute(f.getAbsolutePath());
                    }
                }
            }
    }

    //Add xử lý sự kiện khi drag drog file và thư mục
    public void addTransferHandler(MyTransferHandler handler)
    {
        this.setDragEnabled(true);
        this.setTransferHandler(handler);
        this.setDropMode(DropMode.ON_OR_INSERT);
    }

    //Add xử lý sự kiện khi thư mục hiện hành thay đổi
    public void addDirChangeListener(IDirChangedListener changedListener)
    {
        _changedListener = changedListener;
    }


}
